package com.wayz.util;

import com.wayz.exception.WayzException;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * 时间辅助类
 * 
 * @author:mike.ma
 *
 */
public class TimeHelper {

	/** 常量相关 */
	/** 日期模式 */
	private final static String DATE_PATTERN = "yyyy-MM-dd";
	/** YYYYMMDD日期 */
	private final static String YYYYMMDD_PATTERN = "yyyyMMdd";
	/** 月模式 */
	private final static String MONTH_PATTERN = "yyyy-MM";
	/** 时间模式 */
	private final static String TIME_PATTERN = "HH:mm:ss";
	/** 时间戳模式 */
	private final static String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public static boolean compareDateTime(String time1, String time2) throws WayzException {
		try {
			// 比较日期则写成"yyyy-MM-dd"
			SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_PATTERN);
			// 将字符串形式的时间转化为Date类型的时间
			java.util.Date a = sdf.parse(time1);
			java.util.Date b = sdf.parse(time2);
			// 如果a早于b返回true，否则返回false
			if (a.before(b)) {
				return true;
			}
			return false;
		}
		catch (ParseException e) {
			throw new WayzException("时间格式异常");
		}
	}

	/**
	 * 获取当前日期
	 * 
	 * @return 当前日期字符串
	 */
	public static String getDate() {
		return new SimpleDateFormat(DATE_PATTERN).format(new java.util.Date());
	}

	/**
	 * 获取指定日期
	 * 
	 * @param date 指定日期
	 * @return 指定日期字符串
	 */
	public static String getDate(Date date) {
		// 检查空值
		if (date == null) {
			return null;
		}

		// 转化日期
		return new SimpleDateFormat(DATE_PATTERN).format(date);
	}

	/**
	 * 
	 * <p> 获取YYYYMMDD指定日期</p>
	 * 
	 * @param date
	 * @return
	 * @date 2016年8月1日
	 */
	public static String getYYYYMMDDDate(Date date) {
		// 检查空值
		if (date == null) {
			return null;
		}

		// 转化日期
		return new SimpleDateFormat(YYYYMMDD_PATTERN).format(date);
	}

	/**
	 * 
	 * <p>获取指定月日期</p>
	 * 
	 * @param date
	 * @return
	 * @date 2016年8月1日
	 */
	public static String getMonthDate(Date date) {
		// 检查空值
		if (date == null) {
			return null;
		}

		// 转化日期
		return new SimpleDateFormat(MONTH_PATTERN).format(date);
	}

	/**
	 * 获取指定日期
	 * 
	 * @param date 指定日期
	 * @return 指定日期字符串
	 */

	public static String getDate(java.util.Date date) {
		// 检查空值
		if (date == null) {
			return null;
		}

		// 转化日期
		return new SimpleDateFormat(DATE_PATTERN).format(date);
	}

	/**
	 * 获取指定日期
	 * 
	 * @param date 指定日期字符串
	 * @return 指定日期
	 * @throws WayzException 云歌广告平台异常
	 */
	public static Date getDate(String date) throws WayzException {
		// 检查空值
		if (date == null) {
			return null;
		}

		// 转化日期
		try {
			return new Date(new SimpleDateFormat(DATE_PATTERN).parse(date).getTime());
		}
		catch (ParseException e) {
			throw new WayzException("日期(" + date + ")格式异常");
		}
	}

	/**
	 * 获取当前时间戳
	 * 
	 * @return 当前时间戳字符串
	 */
	public static String getTimestamp() {
		return new SimpleDateFormat(TIMESTAMP_PATTERN).format(new java.util.Date());
	}

	/**
	 * 时间戳转换成日期字符串
	 * 
	 * @param timestamp 时间戳
	 * @return 日期字符串 yyyy-MM-dd HH:mm:ss
	 */
	public static String getDateTime(Long timestamp) {
		return new SimpleDateFormat(TIMESTAMP_PATTERN).format(new Date(timestamp * 1000));
	}

	/**
	 * 
	 * <p> 时间戳转换成日期字符串</p>
	 * 
	 * @param timestamp 时间戳
	 * @return 日期字符串 yyyy-MM-dd HH:mm:ss
	 * @date 2016年4月12日
	 * @author mahao
	 */
	public static String getDate(Long timestamp) {
		return new SimpleDateFormat(TIMESTAMP_PATTERN).format(new Date(timestamp));
	}

	/**
	 * 获取指定时间戳
	 * 
	 * @param timestamp 指定时间戳
	 * @return 指定时间戳字符串
	 */
	public static String getTimestamp(Timestamp timestamp) {
		// 检查空值
		if (timestamp == null) {
			return null;
		}

		// 转化时间
		return new SimpleDateFormat(TIMESTAMP_PATTERN).format(new java.util.Date(timestamp.getTime()));
	}

	/**
	 * 
	 * <p>获取time时间</p>
	 * 
	 * @param time
	 * @return
	 * @date 2016年5月5日
	 * @author mahao
	 */
	public static Timestamp getCurrentTimestamp() {
		// 转化时间
		return new Timestamp(new java.util.Date().getTime());
	}

	/**
	 * 获取指定时间戳
	 * 
	 * @param timestamp 指定时间戳字符串
	 * @return 指定时间戳
	 * @throws WayzException 云歌广告平台异常
	 */
	public static Timestamp getTimestamp(String timestamp) throws WayzException {
		// 检查空值
		if (timestamp == null) {
			return null;
		}

		// 转化时间
		try {
			return new Timestamp(new SimpleDateFormat(TIMESTAMP_PATTERN).parse(timestamp).getTime());
		}
		catch (ParseException e) {
			throw new WayzException("时间戳(" + timestamp + ")格式异常");
		}
	}

	/**
	 * 获取指定时间戳
	 * 
	 * @param timestamp 指定时间戳从1970-1-1 00:00:00开始的毫秒数
	 * @return 指定时间戳
	 */
	public static Timestamp getTimestamp(Long timestamp) {
		// 检查空值
		if (timestamp == null) {
			return null;
		}

		// 转化时间
		return new Timestamp(timestamp);
	}

	/**
	 * 获取当前时间
	 * 
	 * @return 当前时间字符串
	 */
	public static String getTime() {
		return new SimpleDateFormat(TIME_PATTERN).format(new java.util.Date());
	}

	/**
	 * 获取指定时间
	 * 
	 * @param time 指定时间
	 * @return 指定时间字符串
	 */
	public static String getTime(Time time) {
		// 检查空值
		if (time == null) {
			return null;
		}

		// 转化时间
		return new SimpleDateFormat(TIME_PATTERN).format(time);
	}

	/**
	 * 获取指定时间
	 * 
	 * @param time 指定时间
	 * @return 指定时间字符串
	 */
	public static String getTime(Long time) {
		// 检查空值
		if (time == null) {
			return null;
		}

		// 转化时间
		return new SimpleDateFormat(TIME_PATTERN).format(time);
	}

	/**
	 * 获取指定时间
	 * 
	 * @param time 指定时间字符串
	 * @return 指定时间
	 * @throws WayzException 云歌广告平台异常
	 */
	public static Time getTime(String time) throws WayzException {
		// 检查空值
		if (time == null) {
			return null;
		}

		// 转化时间
		try {
			return new Time(new SimpleDateFormat(TIME_PATTERN).parse(time).getTime());
		}
		catch (ParseException e) {
			throw new WayzException("时间(" + time + ")格式异常");
		}
	}

	/**
	 * 获取指定时间的下一小时开始
	 * 
	 * @param time 指定时间
	 * @return 指定时间
	 * @throws WayzException 云歌广告平台异常
	 */
	public static synchronized Time getNextHourTime(Time time) throws WayzException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.HOUR_OF_DAY, 1);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return new Time(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定时间的下一分钟开始
	 * 
	 * @param time 指定时间
	 * @param minutes 增加分钟数
	 * @return 指定时间
	 * @throws WayzException 云歌广告平台异常
	 */
	public static synchronized Time getNextMinuteTime(Time time, int minutes) throws WayzException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		// calendar.add(Calendar.HOUR_OF_DAY, 0);
		calendar.add(Calendar.MINUTE, minutes);
		// calendar.set(Calendar.SECOND, 0);
		return new Time(calendar.getTimeInMillis());
	}

	/**
	 * 获取当前后延秒数时间
	 * 
	 * @param seconds 后延秒数
	 * @return 当前时间字符串
	 */
	public static String getTimestampNextSeconds(int seconds) {
		// 当前时间后延
		Time currentTime = new Time(System.currentTimeMillis() + seconds * 1000);

		// 返回
		return new SimpleDateFormat(TIMESTAMP_PATTERN).format(currentTime);
	}

	/**
	 * 获取加减日期
	 * 
	 * @param date 指定日期
	 * @param days 指定加减天数
	 * @return 加减日期
	 * @throws WayzException 云歌广告平台异常
	 */
	public static synchronized Date getDate(Date date, Integer days) throws WayzException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, days);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取加减日期
	 * 
	 * @param date 指定日期
	 * @param days 指定加减天数
	 * @return 加减日期
	 * @throws WayzException 云歌广告平台异常
	 */
	public static synchronized String getDate(String date, Integer days) throws WayzException {
		Date date1 = getDate(date);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date1);
		calendar.add(Calendar.DATE, days);
		return getDate(new Date(calendar.getTimeInMillis()));
	}

	/**
	 * 
	 * <p>获取Timestap</p>
	 * 
	 * @param timestamp
	 * @param second
	 * @return
	 * @throws WayzException
	 * @date 2017年9月20日
	 */
	public static synchronized Timestamp getTimestamp(Timestamp timestamp, int second) throws WayzException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date(timestamp.getTime()));
		calendar.add(Calendar.SECOND, second);

		return new Timestamp(calendar.getTimeInMillis());
	}

	/**
	 * 获取明年今日日期
	 * 
	 * @return 明年今日日期字符串
	 */
	public static synchronized String getNextYearDate() {
		Calendar calendar = Calendar.getInstance();
		// calendar.setTime(date);
		calendar.add(Calendar.YEAR, 1);

		return new SimpleDateFormat(DATE_PATTERN).format(new Date(calendar.getTimeInMillis()));
	}

	/**
	 * 
	 * <p>获取加减日期</p>
	 * 
	 * @param date 指定日期
	 * @param days 指定加减天数
	 * @return 加减日期
	 * @throws WayzException 云歌广告平台异常
	 * @date 2016年6月7日
	 */
	public static synchronized Date getDate(java.util.Date date, Integer days) throws WayzException {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, days);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取昨日日期
	 * 
	 * @return 昨日日期
	 */
	public static synchronized Date getYesterday() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定日期当年开始时间
	 * 
	 * @param date 指定日期
	 * @return 当年开始时间
	 */
	public static synchronized Date getYearBeginDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定日期当年结束时间
	 * 
	 * @param date 指定日期
	 * @return 当年结束时间
	 */
	public static synchronized Date getYearEndDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.MONTH, 11);
		calendar.set(Calendar.DAY_OF_MONTH, 31);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定日期当月开始时间
	 * 
	 * @param date 指定日期
	 * @return 当月开始时间
	 */
	public static synchronized Date getMonthBeginDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 1);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定日期当天开始时间
	 * 
	 * @param date 指定日期
	 * @param period 统计时段(0:0;1:00-11;2:11-14;3:14-17;4:17-20;5:20-00)
	 * @return 当天开始时间
	 */
	public static synchronized Date getDayBeginHour(Date date, Short period) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		switch (period) {
			case 0: {
				calendar.set(Calendar.HOUR_OF_DAY, 0);
				break;
			}
			case 1: {
				calendar.set(Calendar.HOUR_OF_DAY, 1);
				break;
			}
			case 2: {
				calendar.set(Calendar.HOUR_OF_DAY, 11);
				break;
			}
			case 3: {
				calendar.set(Calendar.HOUR_OF_DAY, 14);
				break;
			}
			case 4: {
				calendar.set(Calendar.HOUR_OF_DAY, 17);
				break;
			}
			case 5: {
				calendar.set(Calendar.HOUR_OF_DAY, 20);
				break;
			}
		}
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取指定日期当天结束时间
	 * 
	 * @param date 指定日期
	 * @param period 统计时段(0:0;1:00-11;2:11-14;3:14-17;4:17-20;5:20-00)
	 * @return 当天结束时间
	 */
	public static synchronized Date getDayEndHour(Date date, Short period) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		switch (period) {
			case 0: {
				calendar.set(Calendar.HOUR_OF_DAY, 23);
				break;
			}
			case 1: {
				calendar.set(Calendar.HOUR_OF_DAY, 10);
				break;
			}
			case 2: {
				calendar.set(Calendar.HOUR_OF_DAY, 13);
				break;
			}
			case 3: {
				calendar.set(Calendar.HOUR_OF_DAY, 16);
				break;
			}
			case 4: {
				calendar.set(Calendar.HOUR_OF_DAY, 19);
				break;
			}
			case 5: {
				calendar.set(Calendar.HOUR_OF_DAY, 23);
				break;
			}
		}
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTimeInMillis());
	}

	/**
	 * 获取年份/月份/日
	 * 
	 * @param date 指定日期
	 * @param item 数据项 1:年,2:月,3:日,4:小时,5:分钟,6:秒
	 * @return 年份/月份/日
	 */
	public static synchronized Integer getDateItem(Date date, int item) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		if (item == 1) {
			return calendar.get(Calendar.YEAR);
		}
		else if (item == 2) {
			return calendar.get(Calendar.MONTH) + 1;
		}
		else if (item == 3) {
			return calendar.get(Calendar.DAY_OF_MONTH);
		}
		else if (item == 4) {
			return calendar.get(Calendar.HOUR_OF_DAY);
		}
		else if (item == 5) {
			return calendar.get(Calendar.MINUTE);
		}
		return calendar.get(Calendar.SECOND);
	}

	/**
	 * 获取时段值,精确到半点
	 * 
	 * @param date 指定日期时间
	 * @return 时段值 如:4 4.5
	 */
	public static synchronized String getHourByDate(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int hour = calendar.get(Calendar.HOUR_OF_DAY);
		int minute = calendar.get(Calendar.MINUTE);
		String hourStr = null;
		if (minute >= 30) {
			hourStr = String.valueOf(hour) + ".5";
		}
		else {
			hourStr = String.valueOf(hour);
		}
		return hourStr;
	}

	/**
	 * 
	 * <p>计算两个日期相差的天数，如果date1 > date2 返回正数，否则返回负数</p>
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 * @date 2016年6月28日
	 */
	public static long getDayDiff(java.util.Date date1, java.util.Date date2) {
		return (date1.getTime() - date2.getTime()) / 86400000;
	}

	/**
	 * 计算两个日期相差秒数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getTimeDelta(java.util.Date date1, java.util.Date date2) {
		long timeDelta = (date1.getTime() - date2.getTime()) / 1000;// 单位是秒
		int secondsDelta = timeDelta > 0 ? (int) timeDelta : (int) Math.abs(timeDelta);
		return secondsDelta;
	}

	/**
	 * 
	 * <p>计算两个日期相差的秒数，如果timestamp1 > timestamp2 返回正数，否则返回负数</p>
	 * 
	 * @param timestamp1
	 * @param timestamp2
	 * @return
	 */
	public static long getTimestampDiff(Timestamp timestamp1, Timestamp timestamp2) {
		return (timestamp1.getTime() - timestamp2.getTime()) / 1000;
	}

	/**
	 * 
	 * <p>计算两个时间相差的秒数，如果time1 > time2 返回正数，否则返回负数</p>
	 * 
	 * @param time1
	 * @param time2
	 * @return 相差的秒数
	 */
	public static long getTimeDiff(Time time1, Time time2) {
		return (time1.getTime() - time2.getTime()) / 1000;
	}

	/**
	 * 
	 * <p>计算两个时间相差的秒数，如果time1 > time2 返回正数，否则返回负数</p>
	 * 
	 * @param time1
	 * @param time2
	 * @return 相差的秒数
	 * @throws WayzException 云歌异常
	 */
	public static long getTimeDiff(String time1, String time2) throws WayzException {
		return (getTime(time1).getTime() - getTime(time2).getTime()) / 1000;
	}

	/**
	 * 2个时间相处秒数
	 * 
	 * @param time1 "2019-11-20 11:30:00"
	 * @param time2 "2019-11-20 12:30:00"
	 * @throws Exception
	 */
	public static int getTimeDelta(String time1, String time2) throws WayzException {
		SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_PATTERN);
		java.util.Date date1 = null;
		java.util.Date date2 = null;
		// 转化时间
		try {
			date1 = sdf.parse(time1);
		}
		catch (ParseException e) {
			throw new WayzException("时间(" + time1 + ")格式异常");
		}
		try {
			date2 = sdf.parse(time2);
		}
		catch (ParseException e) {
			throw new WayzException("时间(" + time2 + ")格式异常");
		}
		return getTimeDelta(date1, date2);
	}

	/**
	 * 
	 * <p>判断是否是周末</p>
	 * 
	 * @param
	 * @return
	 */
	public static boolean isWeekend(Calendar cal) {
		int week = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (week == 6 || week == 0) {// 0代表周日，6代表周六
			return true;
		}
		return false;
	}

	/**
	 * 
	 * 判断是否是周末
	 * 
	 * @param
	 * @return
	 */
	public static synchronized int getWeekDay() {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		cal.setTime(new java.util.Date());
		int day = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (day == 0) {
			day = 7;
		}
		return day;
	}

	/**
	 * 测试
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		/*
		 * Date dd = getDate("2019-08-09"); Time aa = getTime("10:20:30");
		 * System.out.println(getTimestamp(dd.getTime() + aa.getTime()));
		 * 
		 * System.out.println(getTimestampNextSeconds(600));
		 */
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:S");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		java.util.Date date2 = sdf.parse("2019-11-20 11:30:00");
		java.util.Date date1 = sdf.parse("2019-11-20 11:50:15");
		int timeDelta = getTimeDelta(date1, date2);
		// System.out.println(date2);
		// System.out.println(getWeekDay());
		System.out.println(timeDelta);
		long ts = System.currentTimeMillis();
		System.out.println("时间戳:" + ts + "  转化:" + TimeHelper.getTimestamp(ts));
	}

	/**
	 * 获取上月今日的字符串
	 *
	 * @return
	 */
	public static String getPreviousMonth() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new java.util.Date());
		cal.add(Calendar.MONTH, -1);
		// int year3 = cal.get(Calendar.YEAR);
		// int month3 = cal.get(Calendar.MONTH)+1;
		// int day3 = cal.get(Calendar.DAY_OF_MONTH);
		java.util.Date date3 = cal.getTime();
		SimpleDateFormat format3 = new SimpleDateFormat(DATE_PATTERN);
		return format3.format(date3);
	}

	/**
	 * 日期加减天数
	 *
	 * @param date 如果为Null，则为当前时间
	 * @param days 加减天数
	 * @return
	 * @throws ParseException
	 */
	public static String dateAdd(java.util.Date date, int days) throws WayzException {
		SimpleDateFormat sdf = new SimpleDateFormat(TimeHelper.DATE_PATTERN);
		if (date == null) {
			date = new java.util.Date();
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, days);
		return sdf.format(cal.getTime());
	}

	/**
	 * 将字符串年月日转换成日期
	 *
	 * @param strDate
	 * @return
	 * @throws WayzException
	 */
	public static java.util.Date parseDate(String strDate) throws WayzException {
		try {
			return new SimpleDateFormat(DATE_PATTERN).parse(strDate);
		}
		catch (ParseException e) {
			throw new WayzException("日期转换异常");
		}
	}
}
